package com.lzx.orderserver.controller;


import com.lzx.commons.entity.Payment;
import com.lzx.commons.entity.Result;
import com.lzx.commons.utils.ResultUtil;
import com.lzx.orderserver.service.PaymentsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
    //public static final String url = "http://localhost:8001";
    public static final String url = "http://PAYMENTSERVER";

    @Resource
    private RestTemplate restTemplate;

    @Autowired
    private PaymentsService paymentsService;


    @GetMapping("/get")
    public Result<Payment> getPayment(@RequestParam("id")Integer id){
        Result forObject = restTemplate.getForObject(url + "/payment/get?id=" + id, Result.class);
        log.info(forObject.toString());
        System.out.println(forObject.getData().toString());
        return forObject;
    }

    @PostMapping("/create")
    public Result<Payment> create(@RequestBody Payment payment){
        Result result = restTemplate.postForObject(url + "/payment/save", payment, Result.class);
        return result;
    }
    @GetMapping("/testFeign")
    public Result<Payment> testFeign(@RequestParam("id")Integer id){
       return paymentsService.getById(id);
    }
    @GetMapping("/testFeignlist")
    public Result testFeignlist(){
       return paymentsService.list();
    }
    @GetMapping("/asyncTest")
    public Result asyncTest(){

        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Integer> ids = Arrays.asList(1, 2, 3,4);
        List<Result<Payment>> results = ids.stream().map(id -> CompletableFuture.supplyAsync(() -> {
            Result<Payment> byId = paymentsService.getById(id);
            return byId;
        }, executor)).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());
        results.forEach(result-> System.out.println(result.getData().toString()));
        return ResultUtil.success(results);
    }

    @PostMapping("/asyncSave")
    public Result asyncSave(@RequestBody Payment payload){
        Random random = new Random();
        ExecutorService executor = Executors.newFixedThreadPool(100);
        Stream<Integer> boxed = random.ints(100, 0, 100).boxed();
        List<Result> results = boxed.map(integer -> CompletableFuture.supplyAsync(() -> {
            Payment payment = new Payment();
            payment.setSerial(integer.toString());
            Result save = paymentsService.save(payment);
            return save;
        }, executor)).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());
        results.forEach(payment -> System.out.println(payment.toString()));
        return ResultUtil.success(results);
    }

    @PostMapping("/save")
    public Result save(@RequestBody Payment payload){
//        Random random = new Random();
        Result save = paymentsService.save(payload);
        return save;
    }
}
